package com.example.service;

import com.example.model.Equipment;
import com.example.repository.EquipmentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class EquipmentServiceImpl implements EquipmentService {
    
    @Autowired
    private EquipmentRepository equipmentRepository;
    
    @Override
    public Equipment createEquipment(Equipment equipment) {
        return equipmentRepository.save(equipment);
    }
    
    @Override
    public Equipment updateEquipment(Equipment equipment) {
        return equipmentRepository.save(equipment);
    }
    
    @Override
    public void deleteEquipment(Long id) {
        equipmentRepository.deleteById(id);
    }
    
    @Override
    public Optional<Equipment> findById(Long id) {
        return equipmentRepository.findById(id);
    }
    
    @Override
    public Optional<Equipment> findBySerialNumber(String serialNumber) {
        return equipmentRepository.findBySerialNumber(serialNumber);
    }
    
    @Override
    public Page<Equipment> findAllEquipment(Pageable pageable) {
        return equipmentRepository.findAll(pageable);
    }
    
    @Override
    public List<Equipment> findByStatus(Equipment.EquipmentStatus status) {
        return equipmentRepository.findByStatus(status);
    }
    
    @Override
    public List<Equipment> findByType(Equipment.EquipmentType type) {
        return equipmentRepository.findByType(type);
    }
    
    @Override
    public Page<Equipment> findByStatus(Equipment.EquipmentStatus status, Pageable pageable) {
        return equipmentRepository.findByStatus(status, pageable);
    }
    
    @Override
    public List<Equipment> findEquipmentNeedingMaintenance() {
        return equipmentRepository.findEquipmentNeedingMaintenance(LocalDateTime.now());
    }
    
    @Override
    public List<Equipment> findEquipmentNeedingMaintenance(LocalDateTime date) {
        return equipmentRepository.findEquipmentNeedingMaintenance(date);
    }
    
    @Override
    public void updateMaintenanceDate(Long id, LocalDateTime maintenanceDate) {
        Optional<Equipment> equipmentOpt = equipmentRepository.findById(id);
        if (equipmentOpt.isPresent()) {
            Equipment equipment = equipmentOpt.get();
            equipment.setLastMaintenanceDate(maintenanceDate);
            equipmentRepository.save(equipment);
        }
    }
    
    @Override
    public void scheduleNextMaintenance(Long id, LocalDateTime nextMaintenanceDate) {
        Optional<Equipment> equipmentOpt = equipmentRepository.findById(id);
        if (equipmentOpt.isPresent()) {
            Equipment equipment = equipmentOpt.get();
            equipment.setNextMaintenanceDate(nextMaintenanceDate);
            equipmentRepository.save(equipment);
        }
    }
    
    @Override
    public void updateEquipmentStatus(Long id, Equipment.EquipmentStatus status) {
        Optional<Equipment> equipmentOpt = equipmentRepository.findById(id);
        if (equipmentOpt.isPresent()) {
            Equipment equipment = equipmentOpt.get();
            equipment.setStatus(status);
            equipmentRepository.save(equipment);
        }
    }
    
    @Override
    public void markEquipmentAsInUse(Long id) {
        updateEquipmentStatus(id, Equipment.EquipmentStatus.IN_USE);
    }
    
    @Override
    public void markEquipmentAsAvailable(Long id) {
        updateEquipmentStatus(id, Equipment.EquipmentStatus.AVAILABLE);
    }
    
    @Override
    public void markEquipmentForMaintenance(Long id) {
        updateEquipmentStatus(id, Equipment.EquipmentStatus.MAINTENANCE);
    }
    
    @Override
    public void retireEquipment(Long id) {
        updateEquipmentStatus(id, Equipment.EquipmentStatus.RETIRED);
    }
    
    @Override
    public Long countTotalEquipment() {
        return equipmentRepository.count();
    }
    
    @Override
    public Long countByStatus(Equipment.EquipmentStatus status) {
        return (long) equipmentRepository.findByStatus(status).size();
    }
    
    @Override
    public List<Object[]> getEquipmentStatisticsByStatus() {
        return equipmentRepository.countByStatus();
    }
    
    @Override
    public List<Object[]> getEquipmentStatisticsByType() {
        return equipmentRepository.countByType();
    }
}
